/****************************************************
	文件：ResBase.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2020/12/20 18:6:10
	功能：资源项（资源数据）
*****************************************************/

using System;
using System.Collections.Generic;
using HTFW.Core;
using HTFW.Utility.Global;
using UnityEngine;

namespace HTFW.Res
{
    public class ResData : RefCounter, IPoolable, IResultRecord
    {
        /// <summary>
        /// 资源类型
        /// </summary>
        public ResType ResType;

        /// <summary>
        /// 资源加载任务的优先级（异步加载）
        /// </summary>
        public ResTaskPriority Priority;

        /// <summary>
        /// 对Asset资源数据的引用
        /// </summary>
        public UnityEngine.Object Obj;

        /// <summary>
        /// Asset资源路径
        /// </summary>
        public string Path;

        /// <summary>
        /// Asset资源路径对应的Crc
        /// </summary>
        public uint Crc;

        /// <summary>
        /// Asset资源在AB包中的名称
        /// </summary>
        public string AssetName;

        /// <summary>
        /// 加载Asset所需的AB包依赖项名称列表
        /// </summary>
        public List<string> DependencyABNameList;

        /// <summary>
        /// AB依赖项加载完成计数
        /// </summary>
        public int DependencyABCompletedCount;

        /// <summary>
        /// 资源所在AB包的包名
        /// </summary>
        public string ABName;

        /// <summary>
        /// 资源所在AB包，当前AB包资源引用
        /// </summary>
        public AssetBundle AB;

        /// <summary>
        /// 异步加载完成时的回调
        /// </summary>
        public Action OnAsyncLoadDone;

        /// <summary>
        /// 卸载时是否清除内存
        /// </summary>
        public bool IsClearMemory;

        /// <summary>
        /// 资源加载状态
        /// </summary>
        public ResLoadState LoadState;

        /// <summary>
        /// 是否为Sprite资源
        /// </summary>
        public bool IsSprite;

        public int TotalCnt { get; set; }
        public int CurCnt { get; set; }
        public bool IsDone { get; set; }
        public ILoadResult AsyncResult { get; set; }

        public int ObjectPoolIndex { get; set; }

        public ResData()
        {
            DependencyABNameList = new List<string>();
        }

        /// <summary>
        /// 资源数据赋值完后进行的初始化
        /// </summary>
        public void Init()
        {
            if (ResType == ResType.Asset)
            {
                CurCnt = 0;
                TotalCnt = 2; //自身AB包和自身Asset
                if (!DependencyABNameList.IsNullOrEmpty())
                {
                    TotalCnt += DependencyABNameList.Count;
                }

                IsSprite = false;
            }

            IsClearMemory = true;
        }

        public void Dispose()
        {
            Reset();
            AsyncResult = null;
        }

        public override void OnRefZero()
        {
            //资源卸载
            if (ResType == ResType.Asset)
            {
#if UNITY_EDITOR
                if (ResService.IsSimulationMode)
                {
                    if (IsClearMemory)
                    {
                        Obj = null;
                        OnAsyncLoadDone = null;

                        TotalCnt = 0;
                        CurCnt = 0;

                        LoadState = ResLoadState.None;

                        ResCache.Instance.Remove(Path);

                        Resources.UnloadUnusedAssets();
                    }
                    else
                    {
                        OnAsyncLoadDone = null;

                        LoadState = ResLoadState.Loaded;
                    }

                    return;
                }
#endif

                if (IsClearMemory)
                {
                    Obj = null;
                    DependencyABCompletedCount = 0;
                    AB = null;
                    OnAsyncLoadDone = null;

                    TotalCnt = 0;
                    CurCnt = 0;

                    LoadState = ResLoadState.None;

                    ResCache.Instance.Remove(Path);

                    //卸载 AssetBundle
                    for (int i = 0; i < DependencyABNameList.Count; i++) //卸载 依赖项
                    {
                        if (ResCache.Instance.TryGet(DependencyABNameList[i], out ResData abRes))
                            abRes.DecreaseRef();
                    }

                    if (ResCache.Instance.TryGet(ABName, out ResData ownABRes)) //卸载 自身 AB
                        ownABRes.DecreaseRef();
                }
                else
                {
                    OnAsyncLoadDone = null;

                    LoadState = ResLoadState.Loaded;
                }
            }
            else if (ResType == ResType.AssetBundle)
            {
                if (IsClearMemory)
                {
                    AB.Unload(true);
                    AB = null;
                    OnAsyncLoadDone = null;

                    LoadState = ResLoadState.None;

                    ResCache.Instance.Remove(ABName);
                }
                else
                {
                    OnAsyncLoadDone = null;

                    LoadState = ResLoadState.Loaded;
                }
            }
        }

        public void Reset()
        {
            ResetRefCount();
            ResType = ResType.None;
            Priority = ResTaskPriority.None;
            Obj = null;
            Path = "";
            Crc = 0;
            AssetName = "";
            DependencyABNameList.Clear();
            DependencyABCompletedCount = 0;
            ABName = "";
            AB = null;
            OnAsyncLoadDone = null;

            TotalCnt = 0;
            CurCnt = 0;
        }

        //-------------------- For Test --------------------//
        public long LoadStartTime;
        public long LoadEndTime;

        /// <summary>
        /// 加载时间（毫秒）
        /// </summary>
        public long LoadTime
        {
            get { return (LoadEndTime - LoadStartTime) / 10000; }
        }
    }
}